#include "W25Q64.h"
//读取可以跨页，写入不能跨页
void W25Q64_Init(void)
{
	SPI_Init();
}

void W25Q64_ReadID(uint8_t *MID,uint16_t *DID)
{
	SPI_Start();
	SPI_SwapByte(W25Q64_JEDEC_ID);
	*MID = SPI_SwapByte(0xFF);
	*DID = SPI_SwapByte(0xFF);
	*DID <<= 8;
	*DID |= SPI_SwapByte(0xFF);
	SPI_Stop();
}

void W25Q64_Write_Enable(void)
{
	SPI_Start();
	SPI_SwapByte(W25Q64_WRITE_ENABLE);
	SPI_Stop();
}

void W25Q64_WaitBusy(void)
{
	
	SPI_Start();
	SPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1);
	while((SPI_SwapByte(W25Q64_DUMMY_BYTE) & 0x01) == 0x01);
	SPI_Stop();
	
}

void W25Q64_PageProgram(uint32_t Address,uint8_t *DataArray,uint16_t Count)
{
	uint32_t i;
	
	W25Q64_Write_Enable();
	
	SPI_Start();
	SPI_SwapByte(W25Q64_PAGE_PROGRAM);
	SPI_SwapByte(Address >> 16);
	SPI_SwapByte(Address >> 8);
	SPI_SwapByte(Address);
	for(i = 0;i < Count;i++)
	{
		SPI_SwapByte(DataArray[i]);
	}
	SPI_Stop();
	
	W25Q64_WaitBusy();
}

void W25Q64_WriteData(uint32_t Address, uint8_t *DataArray, uint32_t TotalCount) {
    uint32_t remaining = TotalCount;  // 剩余未写入字节数
    uint32_t current_addr = Address;  // 当前写入地址
    uint8_t *current_data = DataArray;  // 当前数据指针

    while (remaining > 0) {
        // 计算当前页内可写入的最大字节数（不超过页大小256字节）
        uint32_t page_remain = 256 - (current_addr % 256);  // 当前页剩余空间
        uint32_t write_len = (remaining < page_remain) ? remaining : page_remain;

        // 写入当前页的数据
        W25Q64_PageProgram(current_addr, current_data, write_len);

        // 更新指针和剩余字节数
        current_addr += write_len;
        current_data += write_len;
        remaining -= write_len;
    }
}

void W25Q64_SectorErase(uint32_t Address)
{
	W25Q64_Write_Enable();
	
	SPI_Start();
	SPI_SwapByte(W25Q64_SECTOR_ERASE_4KB);
	SPI_SwapByte(Address >> 16);
	SPI_SwapByte(Address >> 8);
	SPI_SwapByte(Address);
	SPI_Stop();
	
	W25Q64_WaitBusy();
}
//第 1 块：0x000000（0 ~ 32767 字节）
//第 2 块：0x008000（32768 ~ 65535 字节）
//第 3 块：0x010000（65536 ~ 98303 字节）
//第 4 块：0x018000（98304 ~ 131071 字节）
//第 5 块：0x020000（131072 ~ 163839 字节）
// 32KB块擦除函数
void W25Q64_BlockErase_32K(uint32_t Address) {
    W25Q64_Write_Enable(); // 写使能
    
    SPI_Start();
    SPI_SwapByte(W25Q64_BLOCK_ERASE_32KB); // 0xD8
    SPI_SwapByte(Address >> 16);
    SPI_SwapByte(Address >> 8);
    SPI_SwapByte(Address);
    SPI_Stop();
    
    W25Q64_WaitBusy(); // 等待完成
}

void W25Q64_ReadData(uint32_t Address,uint8_t *DataArray,uint32_t Count)
{
	uint32_t i;
	SPI_Start();
	SPI_SwapByte(W25Q64_READ_DATA);
	SPI_SwapByte(Address >> 16);
	SPI_SwapByte(Address >> 8);
	SPI_SwapByte(Address);
	for(i = 0;i < Count;i++)
	{
		DataArray[i] = SPI_SwapByte(W25Q64_DUMMY_BYTE);
	}
	SPI_Stop();
}

void W25Q64_WriteStatus(void)
{
    W25Q64_Write_Enable(); //写使能
    
    SPI_Start();
    SPI_SwapByte(W25Q64_WRITE_STATUS_REGISTER); //发送写状态寄存器的指令
    SPI_SwapByte(0x00); //写入状态寄存器1
    SPI_SwapByte(0x00); //写入状态寄存器2
    SPI_Stop();
    
    W25Q64_WaitBusy();  //等待忙
}

void W25Q64_WriteSR_1(uint8_t Data){
	
	SPI_Start();
	SPI_SwapByte(W25Q64_SR_WRITE_ENABLE);//使能状态寄存器写入（50h）
	SPI_Stop();
	
	SPI_Start();
	SPI_SwapByte(W25Q64_WRITE_STATUS_REGISTER_1);//状态寄存器写入指令（01h）
	SPI_SwapByte(Data);        //要写入的数据
	SPI_Stop();
	
}
 
//获得SR1寄存器的值
uint8_t W25Q64_GetSR_1(void){
	uint8_t SR_2_Data;
	SPI_Start();
	SPI_SwapByte(W25Q64_READ_STATUS_REGISTER_1);
	SR_2_Data = SPI_SwapByte(W25Q64_DUMMY_BYTE);
	SPI_Stop();
	
	return SR_2_Data;
}
 